<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>~~铖</title>
  <style>
    body {
      height: 100%;
    }

    body {
      align-items: center;
      background-color: #121212;
      color: #fff;
      display: flex;
      font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif;
      font-weight: 100;
      justify-content: center;
      line-height: 1.5;
      text-align: center;
      -webkit-font-smoothing: antialiased;
    }

    canvas {
      height: 100%;
      left: 0;
      position: absolute;
      top: 0;
      width: 100%;
    }

    .page-wrap {
      pointer-events: none;
    }

    .text-container {
      max-width: 420px;
      width: 90%;
    }
  </style>
</head>

<body>
  <canvas id="canvas"></canvas>
  <div class='progress'>
    <div class='progress_inner'>
      <div class='progress_inner__step'>
        <label for='step-1'>html、css、javascript</label>
      </div>
      <div class='progress_inner__step'>
        <label for='step-2'>ajax</label>
      </div>
      <div class='progress_inner__step'>
        <label for='step-3'>vue、node</label>
      </div>
      <div class='progress_inner__step'>
        <label for='step-4'>ts</label>
      </div>
      <div class='progress_inner__step'>
        <label for='step-5'>项目</label>
      </div>
      <input checked='checked' id='step-1' name='step' type='radio'>
      <input id='step-2' name='step' type='radio'>
      <input id='step-3' name='step' type='radio'>
      <input id='step-4' name='step' type='radio'>
      <input id='step-5' name='step' type='radio'>
      <div class='progress_inner__bar'></div>
      <div class='progress_inner__bar--set'></div>
      <div class='progress_inner__tabs'>
        <div class='tab tab-0'>
          <h1>初始阶段（三剑客）：html &nbsp; css &nbsp; javascript</h1>
          <div class="box">
            <div class="box1" style="width:280px;padding-right: 10px;">
              <h3 style="border: 1px dashed skyblue;">html</h3>
            </div>
            <div class="box2" style="width:280px;padding-right: 10px;">
              <h3 style="border: 1px dashed skyblue;">css</h3>
            </div>
            <div class="box3" style="width:280px;padding-right: 10px;">
              <h3 style="border: 1px dashed skyblue;">初级js</h3>
              <div class="content">
                <!-- <a href="./9月/9.18-数据类型作业/数据类型.html">9.18-数据类型作业</a> -->
                <a href="./9月/9.18-数据类型作业/数据类型.html">9.18-数据类型作业</a>
                <a href="./9月/9.20-变量、运算符作业/变量、运算符.html">9.20-变量、运算符作业</a>
                <a href="./9月/9.21-流程控制作业/流程控制作业.html">9.21-流程控制作业</a>
                <a href="./9月/9.22-函数作业/函数.html">9.22-函数作业</a>
                <a href="./9月/9.25-预编译作业/预编译、递归函数.html">9.25-预编译作业</a>
                <a href="./9月/9.26-数组遍历作业/数组遍历.html">9.26-数组遍历作业</a>
                <a href="./9月/9.27-数组遍历2.0作业/数组遍历.html"></a>
                <a href=".10月/10.12-js测试/基础js测试.html">10.12-js测试</a>
                <a href="./10月/10.13-DOM作业/10.13.html">10.13-DOM作业</a>
                <a href="./10月/10.16-练习+作业/练习.html">10.16-练习</a>
                <a href="./10月/10.16-练习+作业/作业.html">10.16-作业</a>
              </div>
            </div>

            <div class="box4" style="width:280px;">
              <h3 style="border: 1px dashed skyblue;">高级js</h3>
              <a href="./10月/10.17-事件作业/">10.17-事件作业</a>
              <a href="./10月/10.18-经典/">10.18-经典轮播图</a>
              <a href="./10月/10.19-无缝/">10.19-无缝轮播图</a>
              <a href="./10月/10.20-分页渲染/">10.20-分页渲染</a>
              <a href="./10月/10.23-随机抽名字/10.23.html">10.23-随机抽名字</a>
              <a href="./10月/10.25-触底加载/触底加载/index.html">10.25-触底加载</a>
              <a href="./10月/10.26-放大镜特效/index.html">10.26-放大镜特效</a>
              <a href="./10月/10.30-ajax渲染轮播图/index.html">10.30-ajax渲染轮播图</a>
              <a href="./11月/11.01-天空之城轮播图/天空之城/index.html"></a>
              <a href="./11月/11.14/练习题目.html">11.14-练习题目</a>
              <a href="./11月/11.17-红绿灯/index.html">11.17-红绿灯</a>
              <a href="./11月/11.20-面向对象经典轮播/经典轮播图/index.html">11.20-面向对象经典轮播</a>
              <!-- <a href="./11月/11.30/dist/index.html">11.30-天空之城产品</a> -->
            </div>

          </div>
        </div>

        <div class='tab tab-1'>
          <h1>礼物准备</h1>
          <p>jQuery的核心特性可以总结为：具有独特的链式语法和短小清晰的多功能接口；具有高效灵活的CSS选择器，并且可对CSS选择器进行扩展；拥有便捷的插件扩展机制和丰富的插件。</p>
        </div>
        <div class='tab tab-2'>
          <h1>礼盒装</h1>
          <p>jQuery的核心特性可以总结为：具有独特的链式语法和短小清晰的多功能接口；具有高效灵活的CSS选择器，并且可对CSS选择器进行扩展；拥有便捷的插件扩展机制和丰富的插件。</p>
        </div>
        <div class='tab tab-3'>
          <h1>装饰盒</h1>
          <p>jQuery的核心特性可以总结为：具有独特的链式语法和短小清晰的多功能接口；具有高效灵活的CSS选择器，并且可对CSS选择器进行扩展；拥有便捷的插件扩展机制和丰富的插件。</p>
        </div>
        <div class='tab tab-4'>
          <h1>送礼物</h1>
          <p>jQuery的核心特性可以总结为：具有独特的链式语法和短小清晰的多功能接口；具有高效灵活的CSS选择器，并且可对CSS选择器进行扩展；拥有便捷的插件扩展机制和丰富的插件。</p>
        </div>
      </div>
      <!-- <div class='progress_inner__status'>
            <div class='box_base'></div>
            <div class='box_lid'></div>
            <div class='box_ribbon'></div>
            <div class='box_bow'>
              <div class='box_bow__left'></div>
              <div class='box_bow__right'></div>
            </div>
            <div class='box_item'></div>
            <div class='box_tag'></div>
            <div class='box_string'></div>
          </div> -->
    </div>
  </div>

  <script>
    // Change the dot count
    const dotCount = 100

    // init global elements
    const canvas = document.getElementById('canvas')
    const ctx = canvas.getContext('2d')
    canvas.width = window.innerWidth
    canvas.height = window.innerHeight
    let pointsRange = Math.min(window.innerWidth, window.innerHeight)
    baseDotRadius = (pointsRange > 300) ? 3 : 1.5
    const maxLineDistance = pointsRange / 2
    let xcenter = ctx.canvas.width / 2
    let ycenter = (ctx.canvas.height / 2)
    let dots = []
    let alpha = 0
    let beta = 0
    let gamma = 0
    let betaScrollAddition = 0
    let gammaScrollAddition = 0
    let timedAngleAddition = 0

    // Helper function
    const randomRange = (min, max) => Math.random() * (max - min) + min

    // Dot Class
    function Dot(x = null, y = null, z = null) {
      this.radius = baseDotRadius,
        this.opacity = 1,
        this.position = {
          x: x || randomRange(-pointsRange, pointsRange),
          y: y || randomRange(-pointsRange, pointsRange),
          z: z || randomRange(-pointsRange, pointsRange),
        }
      this.initialPosition = {
        x: this.position.x,
        y: this.position.y,
        z: this.position.z
      }
    }
    Dot.prototype.update = function () {
      // z position
      let one = this.initialPosition.x * -Math.sin(beta)
      let two = this.initialPosition.y * Math.cos(beta) * Math.sin(gamma)
      let three = this.initialPosition.z * Math.cos(beta) * Math.cos(gamma)
      this.position.z = one + two + three

      // "Depth of field" variables based on z-position
      let zPercentage = this.position.z / pointsRange
      this.radius = baseDotRadius + ((baseDotRadius / 3) * zPercentage)
      this.opacity = 0.5 + ((zPercentage + 1) / 4)
      let depthOfFieldMultiplier = ((zPercentage + 1) / 2) + 0.5

      // x position
      one = this.initialPosition.x * Math.cos(alpha) * Math.cos(beta)
      two = this.initialPosition.y * ((Math.cos(alpha) * Math.sin(beta) * Math.sin(gamma)) - (Math.sin(alpha) * Math.cos(gamma)))
      three = this.initialPosition.z * ((Math.cos(alpha) * Math.sin(beta) * Math.cos(gamma)) + (Math.sin(alpha) * Math.sin(gamma)))
      this.position.x = (one + two + three) * depthOfFieldMultiplier

      // y position
      one = this.initialPosition.x * Math.sin(alpha) * Math.cos(beta)
      two = this.initialPosition.y * ((Math.sin(alpha) * Math.sin(beta) * Math.sin(gamma)) + (Math.cos(alpha) * Math.cos(gamma)))
      three = this.initialPosition.z * ((Math.sin(alpha) * Math.sin(beta) * Math.cos(gamma)) - (Math.cos(alpha) * Math.sin(gamma)))
      this.position.y = (one + two + three) * depthOfFieldMultiplier
    }

    const render = () => {
      timedAngleAddition += 0.05 * Math.PI / 180
      beta = timedAngleAddition + betaScrollAddition
      gamma = timedAngleAddition + gammaScrollAddition

      ctx.clearRect(0, 0, canvas.width, canvas.height)

      // draw dots
      dots.forEach((dot, index) => {

        // update dot position and radius
        dot.update()

        ctx.translate(xcenter + dot.position.x, ycenter + dot.position.y)

        // draw lines
        for (let i = index; i < dots.length; i++) {
          // distance formula to get distance to points
          let distance = Math.sqrt(Math.pow(dots[i].position.x - dot.position.x, 2) + Math.pow(dots[i].position.y - dot.position.y, 2) + Math.pow(dots[i].position.z - dot.position.z, 2))
          if (distance < maxLineDistance) {
            // use the distance to effect the opacity
            ctx.lineWidth = 1
            ctx.strokeStyle = 'rgba(57, 136, 100, ' + ((1 - (distance / maxLineDistance)) / 2) + ')'
            ctx.beginPath()
            ctx.moveTo(0, 0)
            ctx.lineTo(dots[i].position.x - dot.position.x, dots[i].position.y - dot.position.y)
            ctx.stroke()
          }
        }

        // draw dots
        ctx.fillStyle = 'rgba(27, 136, 252, ' + dot.opacity + ')'
        ctx.beginPath()
        ctx.arc(0, 0, dot.radius, 0, 5 * Math.PI)
        ctx.fill()

        // reset transform matrix
        ctx.setTransform(1, 0, 0, 1, 0, 0)
      })

      // loop to draw indefinitely 
      window.requestAnimationFrame(render)
    }

    // mouse move listener
    // document.body.addEventListener('mousemove', (e) => {
    // let rect = e.target.getBoundingClientRect()
    // let percentageX = (e.clientX - rect.left) / document.body.clientWidth
    // let percentageY = (e.clientY - rect.top) / document.body.clientHeight
    // betaScrollAddition = (percentageX * 2 * Math.PI) - Math.PI
    // gammaScrollAddition = -(percentageY * 2 * Math.PI) - Math.PI
    // })

    // resize listenter
    window.addEventListener('resize', () => {
      canvas.width = window.innerWidth
      canvas.height = window.innerHeight
      pointsRange = Math.min(window.innerWidth, window.innerHeight)
    })


    // create the starting dots
    for (let i = 0; i < dotCount; i++) {
      dots.push(new Dot())
    }
    // start animation
    render()
  </script>
</body>

</html>